package com.sun.faces; import javax.faces.FacesException; import javax.faces.application.NavigationHandler; import javax.faces.application.ViewExpiredException; import javax.faces.context.ExceptionHandler; import javax.faces.context.ExceptionHandlerWrapper; import javax.faces.context.FacesContext; import javax.faces.event.ExceptionQueuedEvent; import javax.faces.event.ExceptionQueuedEventContext; import java.util.Iterator; import java.util.Map; public class ViewExpiredExceptionExceptionHandler extends ExceptionHandlerWrapper { private ExceptionHandler wrapped; public ViewExpiredExceptionExceptionHandler(ExceptionHandler wrapped) { this.wrapped = wrapped; } @Override public ExceptionHandler getWrapped() { return this.wrapped; } @Override public void handle() throws FacesException { for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext(); ) { ExceptionQueuedEvent event = i.next(); ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource(); Throwable exception = context.getException(); if (exception instanceof ViewExpiredException) { ViewExpiredException viewExpiredException = (ViewExpiredException) exception; FacesContext facesContext = FacesContext.getCurrentInstance(); Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap(); NavigationHandler navigationHandler = facesContext.getApplication().getNavigationHandler(); try { // Push some useful stuff to the request scope for // use in the page //requestMap.put("currentViewId", viewExpiredException.getViewId()); navigationHandler.handleNavigation(facesContext, null, "/restore/toslow"); facesContext.renderResponse(); } finally { i.remove(); } } } // At this point, the queue will not contain any ViewExpiredEvents. // Therefore, let the parent handle them. getWrapped().handle(); } }